package com.luobd.auth;

import cn.hutool.core.util.StrUtil;
import com.google.common.net.HttpHeaders;
import com.luobd.base.CurrentRequestHolder;
import com.luobd.base.CurrentUserInfo;
import com.luobd.base.service.IAuthService;
import com.luobd.base.util.JWTUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;


public class JWTSecurityAuthenticationFilter extends BasicAuthenticationFilter {


    private final JWTUtil jwtUtil;


    private final IAuthService authService;

    public JWTSecurityAuthenticationFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil, IAuthService authService) {
        super(authenticationManager);
        this.jwtUtil = jwtUtil;
        this.authService = authService;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
        if(authentication != null) {
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
        chain.doFilter(request, response);
    }


    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request){
        UsernamePasswordAuthenticationToken result = null;
        String token = getToken(request);
        if(StrUtil.isNotBlank(token)) {
            CurrentUserInfo subject = jwtUtil.getTokenSubject(token);
            if(subject != null) {
                String cacheToken = authService.getCacheTokenByUserId(subject.getUserInfoId());
                if(StrUtil.isNotBlank(cacheToken) && cacheToken.equals(token)) {
                    CurrentRequestHolder.set(subject);
                    result = new UsernamePasswordAuthenticationToken(subject, cacheToken, Collections.emptyList());
                }
            }
        }
        return result;
    }


    private String getToken(HttpServletRequest request){
        String header = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (header == null || !header.startsWith("Bearer ")){
            return null;
        }
        return header.replace("Bearer ", "");
    }


}
